# coding=utf-8
# @author:      ChengJing
# @name:        utils.py
# @datetime:    2021/7/5 16:07
# @software:    PyCharm
# @description:


import numpy as np
from sklearn.metrics import pairwise_distances as pair
from sklearn.preprocessing import normalize


def construct_graph(features, method='heat', topk=10):
    """
    没有图结构的数据通过计算相似性生成图结构
    Args:
        features:
        method: 计算相似度的方法，one of ['heat','cos','ncos']
        topk: 邻居节点的数量

    Returns:
        knn_graph：np.array，data_type:float32, 通过数据之间的相似性计算的的邻接矩阵
    """

    num = features.shape[0]
    dist = None

    if method == 'heat':
        dist = -0.5 * pair(features) ** 2
        dist = np.exp(dist)
    elif method == 'cos':
        features[features > 0] = 1
        dist = np.dot(features, features.T)
    elif method == 'ncos':
        features[features > 0] = 1
        features = normalize(features, axis=1, norm='l1')
        dist = np.dot(features, features.T)

    inds = np.zeros((num, num))
    for i in range(dist.shape[0]):
        ind = list(np.argpartition(dist[i, :], -(topk + 1))[-(topk + 1):])
        ind.remove(i)
        inds[i, ind] = 1
    return inds.astype(np.float32)


if __name__ == '__main__':

    data = np.random.random((100, 6))
    knn_graph = construct_graph(data)
    print(knn_graph.shape)
    print(knn_graph)
